//
//  TcpManager.swift
//  PeerTalkPlaygroundWithSPM
//
//  Created by Cosmetic Cygia on 2024/8/21.
//

import Foundation

class TcpManager {
    
    private var isShowingMessage: Bool = false
    
    private var stream: URLSessionStreamTask?
    
    private var timeout: Double = 0
    
    init(stream: URLSessionStreamTask, timeout: Double = 0, isShowingMessage: Bool = false) {
        self.stream = stream
        self.timeout = timeout
        self.isShowingMessage = isShowingMessage
    }
    
    func closeManually() {
        
            stream?.closeRead()
            stream?.closeWrite()
            stream?.cancel()
            stream = nil
    }
    
    deinit {
        stream?.closeRead()
        stream?.closeWrite()
        stream?.cancel()
        stream = nil
    }
    
    init(ipAddress: String, port: Int, timeout: Double = 0,isShowingMessage: Bool = false) {
        self.stream = URLSession.shared.streamTask(withHostName: ipAddress, port: port)
        self.timeout = timeout
        self.isShowingMessage = isShowingMessage
    }
    
    func isConnected() -> Bool {
        return (self.stream == nil)
    }
    
    
    func deprecateStreamRead(maxLength: Int = 4096) {
        self.stream?.readData(ofMinLength: 0, maxLength: maxLength, timeout: 0 ) { data, eof, error in
        }
        self.stream?.resume()
    }
    
    func sendString(stringToSend: String, escape: ((_ isSuccess: Bool, _ response: String) -> Void)?) {
        
        let byteArray: [UInt8] = Array(stringToSend.utf8)
        
        self.sendUInt8(dataToSend: byteArray, escape: { isSuccess, response in
            let str = uInt8ToString(byteArray: response)
            
            if (self.isShowingMessage) {
                ELog.d(String(describing: type(of: self)),#function, "Message string Tcp In : \(response)", #line)
                PavaoManager.instance.saveLog(logLevel: LOG_LEVEL.info, logContent: "Message string Tcp In : \(response)")
            }
            
            escape?(isSuccess, str)
        })
    }

    func sendUInt8(dataToSend: [UInt8], bytesToRead: Int = 4096, escape: ((_ isSuccess: Bool, _ response: [UInt8]) -> Void)?) {
        if (self.stream == nil) {
            escape?(false, Array("stream is null".utf8))
        }
        
        let data = Data(dataToSend)
        self.stream?.write(data, timeout: self.timeout) { error in
            if let error = error {
                escape?(false, Array(error.localizedDescription.utf8))
            }
            else {
                self.stream?.readData(ofMinLength: 0, maxLength: bytesToRead, timeout: self.timeout ) { data, eof, error in
                    if let error = error {
                        escape?(false, Array(error.localizedDescription.utf8))
                    } else if let receivedData = data {
                        
                        let response = [UInt8](receivedData)
                        if (self.isShowingMessage) {
                            ELog.d(String(describing: type(of: self)),#function, "Message [UInt8] Tcp In : \(response)", #line)
                            PavaoManager.instance.saveLog(logLevel: LOG_LEVEL.info, logContent: "Message [UInt8] Tcp In : \(response)")
                        }
                        
                        escape?(true, response)
                    }
                }
            }
        }
        self.stream?.resume()
    }
}
